package io.gitee.kotle.android.utils

import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
import io.gitee.kotle.android.adapter.RecyclerViewHolder
import io.gitee.kotle.android.iInterface.ILifecycleObserver
import kotlinx.coroutines.*

/**
 *
 * 描述：
 *
 * 创建人：jiale.wei
 * 创建时间：2021/11/24 9:38 上午
 *
 */
/**
 * 自动循环任务
 */
class TickTask(
    var time: Long,/*时间间隔*/
    val runnable: suspend CoroutineScope.() -> Unit
) : ILifecycleObserver {
    companion object {
        /**
         * 启动轮询,必须手动取消，否则内存泄露
         */
        fun start(
            time: Long = 1000L,
            block: suspend CoroutineScope.() -> Unit
        ): TickTask {
            return TickTask(time, block).also {
                it.start()
            }
        }

        /**
         * 带有生命周期的启动
         */
        fun startWithLifecycleOwner(
            owner: LifecycleOwner,
            time: Long = 1000L,
            block: suspend CoroutineScope.() -> Unit
        ): TickTask {
            val task = start(time, block)
            owner.lifecycle.addObserver(task)
            return task
        }

        /**
         * 停止轮询
         */
        fun TickTask.stop() {
            cancel()
        }
    }

    private val coroutineScope = MainScope()

    /**
     * job
     *
     */
    private var job: Job? = null

    /**
     * 延时多少时间开始执行
     */
    var delayStartDuration: Long = 0

    /**
     * run
     */
    @Synchronized
    fun start() {
        if (isRunning) {
            return
        }
        val block: suspend CoroutineScope.() -> Unit = {
            while (isActive) {
                runnable.invoke(this)
                delay(time)
            }
        }
        job = coroutineScope.launch {
            val delayDuration = delayStartDuration
            if (delayDuration > 0) {
                delay(delayDuration)
            }
            block.invoke(this)
        }
    }

    /**
     * 是否正运行
     */
    val isRunning
        get() = job?.isActive == true

    /**
     * 取消回调
     */
    fun cancel() {
        onlyCancelJob()
        job = null
    }

    /**
     * 生命周期可见
     */
    override fun onStart() {
        super.onStart()
        //如果取消的时候正在运行，则自动恢复
        //如果用户取消，job是null，否则是自动取消，需要恢复
        if (job != null) {
            start()
        }
    }

    /**
     * 生命周期不可见
     */
    override fun onStop() {
        super.onStop()
        onlyCancelJob()
    }

    override fun onDestroy() {
        super.onDestroy()
        cancel()
        if (coroutineScope.isActive) {
            coroutineScope.cancel()
        }
    }

    /**
     * 取消job，变量不赋值为null，
     */
    private fun onlyCancelJob() {
        if (isRunning) {
            job?.cancel()
        }
    }
}

/**
 * 带有轮询任务的Holder
 */
abstract class RecyclerViewTickTaskHolder<DataType, Binding : ViewBinding?> :
    RecyclerViewHolder<DataType, Binding> {

    constructor(binding: Binding) : super(binding)
    constructor(itemView: View) : super(itemView)

    private var tickTask: TickTask? = null

    init {
        itemView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
            override fun onViewAttachedToWindow(p0: View) {
                tickTask?.start()
            }

            override fun onViewDetachedFromWindow(p0: View) {
                tickTask?.cancel()
            }

        })
    }

    override fun onViewRecycled() {
        super.onViewRecycled()
        cancelTickTask()
    }

    /**
     * 开始轮询任务
     */
    fun startTickTask(
        time: Long/*轮询的间隔时间*/,
        lifecycleOwner: LifecycleOwner? = null
    ) {
        if (tickTask?.isRunning == true) {
            return
        }
        if (lifecycleOwner != null) {
            tickTask = TickTask.startWithLifecycleOwner(lifecycleOwner, time, ::onTick)
            return
        }
        //判断fragment
        val fragment = bindingParent?.findFragment<Fragment>()
        if (fragment != null) {
            tickTask = TickTask.startWithLifecycleOwner(fragment, time, ::onTick)
            return
        }
        //利用activity的生命周期启动
        tickTask = TickTask.startWithLifecycleOwner(itemView.appCompatActivity, time, ::onTick)
    }

    /**
     * 取消轮询任务
     */
    fun cancelTickTask() {
        tickTask?.cancel()
        tickTask = null
    }

    abstract suspend fun onTick(scope: CoroutineScope)
}
